package com.icedevcloud.upms.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.icedevcloud.common.core.exception.ApiException;
import com.icedevcloud.common.core.page.PageResult;
import com.icedevcloud.upms.api.user.dto.QueryUserResDto;
import com.icedevcloud.upms.controller.admin.user.dto.*;
import com.icedevcloud.upms.entity.SysRole;
import com.icedevcloud.upms.entity.SysUser;
import com.icedevcloud.upms.entity.SysUserRole;
import com.icedevcloud.upms.mapper.SysUserMapper;
import com.icedevcloud.upms.service.ISysRoleService;
import com.icedevcloud.upms.service.ISysUserRoleService;
import com.icedevcloud.upms.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author XiaoBingBy
 * @since 2023-08-12
 */
@RequiredArgsConstructor
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    private final ISysRoleService iSysRoleService;
    private final ISysUserRoleService iSysUserRoleService;

    @Override
    public PageResult<UserExtResDto> userPage(UserPageReqDto reqDto) {
        Page<SysUser> page = new Page<>(reqDto.getPage(), reqDto.getPageSize());
        page.setOptimizeCountSql(false);
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(StrUtil.isNotBlank(reqDto.getUsername()), SysUser::getUsername, reqDto.getUsername())
                .eq(StrUtil.isNotBlank(reqDto.getNickname()), SysUser::getNickname, reqDto.getNickname())
                .eq(StrUtil.isNotBlank(reqDto.getPhone()), SysUser::getPhone, reqDto.getPhone())
                .eq(StrUtil.isNotBlank(reqDto.getEmail()), SysUser::getEmail, reqDto.getEmail())
                .eq(reqDto.getDeptId() != null, SysUser::getDeptId, reqDto.getDeptId());
        queryWrapper.eq(reqDto.getStatus() != null, "u.status", reqDto.getStatus());
        IPage<UserExtResDto> result = baseMapper.selectUserListPage(
                page,
                queryWrapper
        );

        result.getRecords().forEach(item -> item.setPassword(null));

        PageResult<UserExtResDto> pageResult = new PageResult<>();
        pageResult.setRecords(result.getRecords());
        pageResult.setTotal(result.getTotal());
        pageResult.setPage(result.getCurrent());
        pageResult.setPageSize(result.getSize());
        pageResult.setPages(result.getPages());
        return pageResult;
    }

    @Override
    public QueryUserResDto queryUserByUsername(String username) {
        SysUser user = this.getOne(
                Wrappers.<SysUser>lambdaQuery()
                        .eq(SysUser::getUsername, username)
                        .eq(SysUser::getStatus, 1)
        );
        if (user == null) {
            return null;
        }
        QueryUserResDto resDTO = new QueryUserResDto();
        resDTO.setId(user.getId());
        resDTO.setTenantNo(user.getTenantNo());
        resDTO.setUsername(user.getUsername());
        resDTO.setNickname(user.getNickname());
        resDTO.setPassword(user.getPassword());
        return resDTO;
    }

    @Override
    public UserInfoResDto getUserInfo() {
        SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, "admin"));
        if (sysUser == null) {
            throw new ApiException("用户不存在");
        }
        UserInfoResDto resDto = new UserInfoResDto();
        resDto.setUserId(sysUser.getId());
        resDto.setUsername(sysUser.getUsername());
        resDto.setNickname(sysUser.getNickname());
        resDto.setRealName(sysUser.getNickname());
        resDto.setAvatar(sysUser.getAvatar());
        resDto.setHomePath("");
        SysRole userRole = iSysRoleService.getRoleByUserId(sysUser.getId());
        if (userRole != null) {
            UserInfoResDto.SimpleUserInfoRoleDto simpleUserInfoRoleDto = new UserInfoResDto.SimpleUserInfoRoleDto();
            simpleUserInfoRoleDto.setRoleName(userRole.getRoleName());
            simpleUserInfoRoleDto.setValue(userRole.getRoleCode());
            resDto.setRoles(ListUtil.of(simpleUserInfoRoleDto));
        }
        return resDto;
    }

    @Override
    public Boolean userNameExist(String username) {
        long count = this.count(
                Wrappers.<SysUser>lambdaQuery()
                        .eq(SysUser::getUsername, username)
        );
        if (count > 0) {
            throw new ApiException("用户名已存在");
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(AddUserReqDto reqDto) {
        SysUser existUser = this.getOne(
                Wrappers.<SysUser>lambdaQuery()
                        .eq(SysUser::getUsername, reqDto.getUsername())
        );
        if (existUser != null) {
            throw new ApiException("用户名已存在");
        }

        SysRole role = iSysRoleService.getById(reqDto.getRoleId());
        if (role == null) {
            throw new ApiException("角色不存在");
        }

        SysUser sysUser = BeanUtil.copyProperties(reqDto, SysUser.class);
        String hashpw = BCrypt.hashpw(sysUser.getPassword());
        sysUser.setPassword(hashpw);
        this.save(sysUser);

        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setUserId(sysUser.getId());
        sysUserRole.setRoleId(role.getId());
        iSysUserRoleService.save(sysUserRole);
        return Boolean.TRUE;
    }

    @Override
    public Boolean update(UpdateUserReqDto reqDto) {
        SysUser sysUser = this.getOne(
                Wrappers.<SysUser>lambdaQuery()
                        .eq(SysUser::getId, reqDto.getId())
        );
        if (sysUser == null) {
            throw new ApiException("用户不存在");
        }

        SysRole role = iSysRoleService.getById(reqDto.getRoleId());
        if (role == null) {
            throw new ApiException("角色不存在");
        }
        SysUserRole sysUserRole = iSysUserRoleService.getOne(
                Wrappers.<SysUserRole>lambdaQuery()
                        .eq(SysUserRole::getUserId, sysUser.getId())
        );
        if (sysUserRole != null) {
            Long roleId = sysUserRole.getRoleId();
            if (ObjectUtil.notEqual(roleId, reqDto.getRoleId())) {
                sysUserRole.setRoleId(reqDto.getRoleId());
                iSysUserRoleService.updateById(sysUserRole);
            }
        } else {
            sysUserRole = new SysUserRole();
            sysUserRole.setUserId(sysUser.getId());
            sysUserRole.setRoleId(reqDto.getRoleId());
            iSysUserRoleService.save(sysUserRole);
        }

        BeanUtil.copyProperties(reqDto, sysUser);
        return this.updateById(sysUser);
    }

    @Override
    public Boolean delete(Long id) {
        SysUser sysUser = this.getOne(
                Wrappers.<SysUser>lambdaQuery()
                        .eq(SysUser::getId, id)
        );
        if (sysUser == null) {
            throw new ApiException("用户不存在");
        }
        iSysUserRoleService.removeUserRoleByUserId(id);
        return this.removeById(id);
    }

}
